{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "warnings.simplefilter('ignore')\n",
    "import seaborn as sns\n",
    "\n",
    "sns.set_context(rc={'figure.figsize': (14, 7) } )\n",
    "figzize_me = figsize =(14, 7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 第一章 初识机器学习\n",
    "\n",
    "本章依赖的python类库有：\n",
    "\n",
    "- numpy 快速操作结构数组的工具\n",
    "- pandas 数据分析处理工具\n",
    "- matplotlib 画图工具\n",
    "- sklearn 机器学习库\n",
    "- seaborn 基于matplotlib封装的统计绘图工具\n",
    "- abupy 开源的量化系统，内含ml_fit机器学习模块，[abupy开源地址](https://github.com/bbfamily/abu)，[abupy环境搭建教程](http://www.abuquant.com/lecture/lecture_0.html)\n",
    "\n",
    "安装教程见实体书附录A，每个小节可以独立运行。\n",
    "\n",
    "____"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.2 KNN（K-NearestNeighbor K-近邻算法）——相似的邻居请投票"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np # numpy可以快速操作结构数组\n",
    "\n",
    "vec1 = np.array([1, 2, 3])\n",
    "vec2 = np.array([4, 5, 6])\n",
    "# 欧氏距离\n",
    "assert np.linalg.norm(vec1 - vec2) == np.sqrt(np.sum(np.square(vec1 - vec2)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 鸢尾花卉数据集（IRIS）\n",
    "\n",
    "#### 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import numpy as np # 快速操作结构数组的工具\n",
    "import pandas as pd # 数据分析处理工具\n",
    "import matplotlib.pyplot as plt # 画图工具\n",
    "from sklearn import datasets # 机器学习库\n",
    "\n",
    "#数据集 0-setosa、1-versicolor、2-virginica\n",
    "scikit_iris = datasets.load_iris()\n",
    "# 转换成pandas的DataFrame数据格式，方便观察数据\n",
    "iris = pd.DataFrame(data=np.c_[scikit_iris['data'], scikit_iris['target']],\n",
    "                     columns=np.append(scikit_iris.feature_names, ['y']))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sepal length (cm)</th>\n",
       "      <th>sepal width (cm)</th>\n",
       "      <th>petal length (cm)</th>\n",
       "      <th>petal width (cm)</th>\n",
       "      <th>y</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>5.1</td>\n",
       "      <td>3.5</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>4.9</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1.4</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)  \\\n",
       "0                5.1               3.5                1.4               0.2   \n",
       "1                4.9               3.0                1.4               0.2   \n",
       "\n",
       "     y  \n",
       "0  0.0  \n",
       "1  0.0  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "iris.head(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "sepal length (cm)    0\n",
       "sepal width (cm)     0\n",
       "petal length (cm)    0\n",
       "petal width (cm)     0\n",
       "y                    0\n",
       "dtype: int64"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 检查数据是否有缺失\n",
    "iris.isnull().sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sepal length (cm)</th>\n",
       "      <th>sepal width (cm)</th>\n",
       "      <th>petal length (cm)</th>\n",
       "      <th>petal width (cm)</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>y</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0.0</th>\n",
       "      <td>50</td>\n",
       "      <td>50</td>\n",
       "      <td>50</td>\n",
       "      <td>50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1.0</th>\n",
       "      <td>50</td>\n",
       "      <td>50</td>\n",
       "      <td>50</td>\n",
       "      <td>50</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2.0</th>\n",
       "      <td>50</td>\n",
       "      <td>50</td>\n",
       "      <td>50</td>\n",
       "      <td>50</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)\n",
       "y                                                                            \n",
       "0.0                 50                50                 50                50\n",
       "1.0                 50                50                 50                50\n",
       "2.0                 50                50                 50                50"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 观察样本中按类别数量是否比较均衡\n",
    "iris.groupby('y').count()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1.])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选择全部特征训练模型\n",
    "X = iris[scikit_iris.feature_names]\n",
    "# label\n",
    "y = iris['y']\n",
    "\n",
    "# 第一步，选择model\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "knn = KNeighborsClassifier(n_neighbors=1)\n",
    "# 第二步，fit X、y\n",
    "knn.fit(X, y)\n",
    "# 第三步，predict新数据\n",
    "knn.predict([[3, 2, 2, 5]])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 分割训练集和测试集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "accuracy: ：0.973684210526\n"
     ]
    }
   ],
   "source": [
    "from abupy import train_test_split\n",
    "from sklearn import metrics\n",
    "\n",
    "# 分割训练-测试集\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=4)\n",
    "\n",
    "# K=15\n",
    "knn = KNeighborsClassifier(n_neighbors=15)\n",
    "knn.fit(X_train, y_train)\n",
    "\n",
    "y_pred_on_train = knn.predict(X_train)\n",
    "y_pred_on_test = knn.predict(X_test)\n",
    "# print(metrics.accuracy_score(y_train, y_pred_on_train))\n",
    "print('accuracy: ：{}'.format(metrics.accuracy_score(y_test, y_pred_on_test)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### abupy\n",
    "\n",
    "[开源项目地址](https://github.com/bbfamily/abu)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "KNeighborsClassifier score mean: 0.973333333333\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([ 0.9333,  0.9333,  1.    ,  1.    ,  1.    ,  0.9333,  0.9333,\n",
       "        1.    ,  1.    ,  1.    ])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from abupy import AbuML\n",
    "\n",
    "# IRIS花卉数据集\n",
    "iris = AbuML.create_test_fiter()\n",
    "\n",
    "# 使用KNN\n",
    "iris.estimator.knn_classifier(n_neighbors=15)\n",
    "\n",
    "# cross-validation测试\n",
    "iris.cross_val_accuracy_score()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.3 逻辑分类I：线性分类模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "def score(x, w, b):\n",
    "    \"\"\"线性函数\"\"\"\n",
    "    return np.dot(x, w) + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def sigmoid(s):\n",
    "    \"\"\"sigmoid函数\"\"\"\n",
    "    return 1. / (1 + np.exp(-s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def softmax(s):\n",
    "    \"\"\"softmax函数\"\"\"\n",
    "    return np.exp(s) / np.sum(np.exp(s), axis=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 体验softmax\n",
    "\n",
    "1\\."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x115500250>,\n",
       " <matplotlib.lines.Line2D at 0x115500450>,\n",
       " <matplotlib.lines.Line2D at 0x115500590>]"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\npwAjIiIiH8q++h7+8NxOWgZ7Xc49oYwLlk/CYVevi4iMPAUYEREROS7hSIzHX6vhH+sHel2KclO5\n+tyZlBelm12aiIwjxwww8XicH//4x+zevRun08lPfvITysrKhvY/9dRT3HfffVitVi655BI+/elP\nj2jBIiIiMvoOtfRxz1PbaeoIYLVYOPfEUs5fpl4XERl9xwwwL774IuFwmIceeoiqqipuuukm7r77\n7qH9P//5z3nmmWfweDysWrWKVatWkZGh8a8iIiJjQdwweGHdIR5/tYZY3GBCjod/O28Wkyeo10VE\nzHHMALNx40ZOOeUUACorK6murj5i//Tp0+nr68Nut2MYBhbdpEpERGRM6OwN8vtndrDrUDcAKxYW\nc/mKKbg0w5iImOiYAcbn85GWljb03GazEY1GsdsHXjp16lQuueQS3G43K1euJD39g/8ik5Xlwa7u\n5jElL89rdgkyTqntiZnGevt7vaqBux7dgr8/Qmaai2+trmTJrEKzyxLGftuTxJYI7e+YASYtLQ2/\n3z/0PB6PD4WXXbt28corr/DSSy/h8Xj43ve+x/PPP88555xz1Pfr6goMQ9mSKPLyvLS19ZldhoxD\nantiprHc/vpDUf7373tYu70ZgHkVOVx97kzSU51j9mdOJmO57UniG83290FB6ZgBZuHChbz88suc\ne+65VFVVMW3atKF9Xq+XlJQUXC4XNpuN7Oxsent7h6dqERERGVX7G3q456nttPcEcdqtrD5jCqcv\nKNbwcBFJKMcMMCtXruTNN9/kiiuuwDAMfvrTn/L0008TCARYvXo1q1ev5tOf/jQOh4PS0lIuuuii\n0ahbREREholhGPx9fR2PvrKfWNygrMDLNefPYkJOqtmliYi8h8UwDGM0T6huz7FFXdliFrU9MdNY\nan++/gj3PruTqn3tAHxySQmXnl6B3WY1uTJ5P2Op7UnySZohZCIiIjI27Wvo4Z4nq+noDeFx2fnS\nqpksmJZndlkiIh9IAUZERGSciRsGf19Xx2OvDgwZKy9K59rzZ5Ob6Ta7NBGRY1KAERERGUd8/RH+\n8MwOtuzvADRkTESSjwKMiIjIOLG/sYe7n6imszdEaoqdq1fNZMFUDRkTkeSiACMiIjIOvFLVwJ//\nsYdobHDI2AWzyc3QkDERST4KMCIiImNYJBrjT//Yw2tbmgD4xMKJrP7EFA0ZE5GkpQAjIiIyRnX2\n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\noOs6Dz/8MA888ACf/vSn6e3tNbtJYplIpVJ85Stf4aGHHuK+++7jT3/6k9lNEsvQ5OQku3btoru7\n2+ymiGXke9/7Hg888AAf+9jHePLJJ81uDqrZDRC564c//CHXXnstn/3sZzlx4gR/93d/x29+8xuz\nmyXy3IsvvkgymeSJJ56gvb2db37zmzz22GNmN0ssA08//TSFhYV8+9vfZnp6mo985CPccsstZjdL\nLCOpVIqHH34Yp9NpdlPEMrJ792727dvHL37xC2KxGD/4wQ/MbpIEGHHlPvvZz2K32wFIp9M4HA6T\nWySWg7a2Nm688UYANm/ezMGDB01ukVgu7rjjDm6//XYADMNAURSTWySWm29961s8+OCD/Md//IfZ\nTRHLyBtvvEFLSwtf+MIXCIfDfPWrXzW7SRJgxKV58skn+fGPfzzntUceeYTW1lbGx8f5yle+wj/+\n4z+a1DqxnITDYbxeb/a5oihomoaqSncmFpbH4wEyNfjFL36RL33pSya3SCwnv/71rykuLubGG2+U\nACMWVSAQYGhoiO9+97sMDAzwN3/zN/zxj3/EYrGY1iY54otLcv/993P//fef9XpnZydf/vKX+epX\nv8rOnTtNaJlYbrxeL5FIJPtc13UJL2LRDA8P84UvfIGHHnqIe+65x+zmiGXkqaeewmKx8NZbb3Hk\nyBH+/u//nscee4yysjKzmybyXGFhIY2NjdjtdhobG3E4HExNTVFSUmJam+QifnHFjh8/zt/+7d/y\nne98h127dpndHLFMbN26lddeew2A9vZ2WlpaTG6RWC4mJib43Oc+x1e+8hXuu+8+s5sjlpnHH3+c\nn/3sZ/z0pz9l7dq1fOtb35LwIhbFtm3beP311zEMg9HRUWKxGIWFhaa2ST62FFfsO9/5Dslkkn/+\n538GMp+My8XUYqHdeuutvPnmmzz44IMYhsEjjzxidpPEMvHd736XYDDIo48+yqOPPgrA97//fbmg\nWgiR197//vezZ88e7rvvPgzD4OGHHzb9GkCLYRiGqS0QQgghhBBCiEskQ8iEEEIIIYQQOUMCjBBC\nCCGEECJnSIARQgghhBBC5AwJMEIIIYQQQoicIQFGCCGEEEIIkTMkwAghhBBCCCFyhgQYIYQQQggh\nRM74/wESnLd5aQrwOAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1152079d0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "# seaborn是一个matplotlib之上封装统计plot类库，这里我们只是使用seaborn的样式定义\n",
    "import seaborn as sns\n",
    "\n",
    "x = np.arange(-3.0, 6.0, 0.1)\n",
    "scores = np.vstack([x, np.ones_like(x), 0.2*np.ones_like(x)])\n",
    "plt.plot(x, softmax(scores).T, linewidth=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2\\."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 0.659   0.2424  0.0986]\n",
      "[ 1.  0.  0.]\n",
      "[ 0.3366  0.3332  0.3302]\n"
     ]
    }
   ],
   "source": [
    "scores = np.array([2.0, 1.0, 0.1])\n",
    "print(softmax(scores))\n",
    "print(softmax(scores * 100))\n",
    "print(softmax(scores / 100))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# y是真实标签，p是预测概率\n",
    "def cross_entropy(y, p):\n",
    "    \"\"\"交叉熵\"\"\"\n",
    "    return np.sum(y * np.log(p) + (1 - y) * np.log(1 - p, axis=1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.4 逻辑分类II：线性分类模型\n",
    "\n",
    "### 寻找模型的权重"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "49"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# 函数y = 1*x^2 + 0*x + 0\n",
    "y = np.poly1d([1, 0, 0])\n",
    "y(-7)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-14"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# d_yx：导函数\n",
    "d_yx = np.polyder(y)\n",
    "d_yx(-7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1\\."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-7.950444685727838, 9.870139392489492)"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import random\n",
    "\n",
    "# 随机选一个起点 \n",
    "x_0 = random.uniform(-10, 10)\n",
    "y_0 = random.uniform(-10, 10)\n",
    "x_0, y_0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2\\."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "-4.7702668114367022"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def step(x, d_yx):\n",
    "    alpha = .2\n",
    "    return x - alpha*d_yx(x)\n",
    "step(x_0, d_yx)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3\\. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[-7.950444685727838,\n",
       " -4.7702668114367022,\n",
       " -2.8621600868620209,\n",
       " -1.7172960521172125,\n",
       " -1.0303776312703274,\n",
       " -0.61822657876219644,\n",
       " -0.37093594725731782,\n",
       " -0.2225615683543907,\n",
       " -0.13353694101263441,\n",
       " -0.080122164607580648,\n",
       " -0.04807329876454839]"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = x_0\n",
    "x_list = [x]\n",
    "for i in range(10):\n",
    "    x = step(x, d_yx)\n",
    "    x_list.append(x)\n",
    "x_list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 去均值与归一化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 均值\n",
    "x = np.array([1, 2, 3, 4, 5])\n",
    "assert np.mean(x) == np.sum(x) / 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 方差\n",
    "assert np.std(x) == np.sqrt(np.mean((x - np.mean(x))**2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# 两条特征向量\n",
    "f1 = np.array([0.2, 0.5, 1.1]).reshape(-1, 1)\n",
    "f2 = np.array([-100.0, 56.0, -77.0]).reshape(-1, 1)\n",
    "\n",
    "# 计算归一化\n",
    "f1_scaled = (f1 - np.mean(f1)) / np.std(f1)\n",
    "f2_scaled = (f2 - np.mean(f2)) / np.std(f2)\n",
    "\n",
    "# 用sklearn封装的函数计算归一化\n",
    "import sklearn.preprocessing as preprocessing\n",
    "scaler = preprocessing.StandardScaler()\n",
    "f1_sk_scaled = scaler.fit_transform(f1)\n",
    "f2_sk_scaled = scaler.fit_transform(f2)\n",
    "\n",
    "assert np.allclose(f1_sk_scaled, f1_scaled) and np.allclose(f2_sk_scaled, f2_scaled)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实现"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "LogisticRegression score mean: 0.973333333333\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "array([ 1.    ,  0.9333,  1.    ,  1.    ,  0.9333,  0.9333,  0.9333,\n",
       "        1.    ,  1.    ,  1.    ])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from abupy import AbuML\n",
    "import sklearn.preprocessing as preprocessing\n",
    "\n",
    "# IRIS花卉数据集\n",
    "iris = AbuML.create_test_fiter()\n",
    "\n",
    "# 使用逻辑分类，损失函数指定为交叉熵\n",
    "iris.estimator.logistic_classifier(multi_class='multinomial', solver='lbfgs')\n",
    "\n",
    "# cross-validation测试\n",
    "iris.cross_val_accuracy_score()"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
